/*
 * Copyright 2016-2019 yoara
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yhao.infra.common.threads;

import org.springframework.beans.BeanUtils;
import yhao.infra.common.ContextHolder;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * 本地线程池Callable实现
 * <p>使用本地线程池必须使用本类实现，必须附带上下文信息，避免线程数据丢失
 *
 * @see ThreadFixedPool
 * @see ThreadCachePool
 * @author yoara
 */
public abstract class LocalCallable<V> implements Callable<V> {
    private Map<String, Object> contextHolder;

    public LocalCallable() {
        Map<String, Object> pContextHolder = ContextHolder.getContextHolder();
        if(pContextHolder!=null){
            contextHolder = new HashMap<>();
            BeanUtils.copyProperties(pContextHolder,contextHolder);
        }
    }

    @Override
    public V call() throws Exception {
        ContextHolder.setContextHolder(contextHolder);
        return doCall();
    }

    abstract protected V doCall() throws Exception;
}
